package com.epfuse.cloud.common.redis.serializer;


import com.epfuse.cloud.common.redis.serializer.annotation.EpfuseRedisSerializer;
import com.epfuse.cloud.common.redis.serializer.enums.SerializerType;
import com.epfuse.cloud.common.redis.serializer.impl.JdkSerializer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @ClassName DefaultSerializerProvider
 * @Description TODO
 * @Author 孙峰
 * @Date 2023/3/8 17:07
 */

public class DefaultSerializerProvider implements SerializerProvider, ApplicationContextAware {

    private static final Log logger = LogFactory.getLog(DefaultSerializerProvider.class);
    private final RedisSerializerProperties serializerConfig;

    public DefaultSerializerProvider(RedisSerializerProperties serializerConfig) {
        this.serializerConfig = serializerConfig;
    }

    /**
     * 存放所有序列化方式的容器
     */
    private Map<SerializerType, AbstractRedisSerializer> serializerMap = new ConcurrentHashMap<>();
    /**
     * 实际的编码器提供者
     */
    private AbstractRedisSerializer serializer;

    /**
     * 获取默认配置的序列化方式
     *
     * @return
     */
    @Override
    public AbstractRedisSerializer getSerializer() {
        return serializer;
    }

    /**
     * 指定类型的序列化方式
     *
     * @param serializerType
     * @return
     */
    @Override
    public AbstractRedisSerializer getSerializer(SerializerType serializerType) {
        if (AbstractRedisSerializer.isEmpty(serializerType)) {
            throw new IllegalArgumentException("请传入正确的SerializerType");
        }
        return serializerMap.get(serializerType);
    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        Map<String, Object> map = applicationContext.getBeansWithAnnotation(EpfuseRedisSerializer.class);
        for (Object bean : map.values()) {
            EpfuseRedisSerializer epfuseRedisSerializer = bean.getClass().getAnnotation(EpfuseRedisSerializer.class);
            serializerMap.put(epfuseRedisSerializer.serializer(), (AbstractRedisSerializer) bean);
            if (epfuseRedisSerializer.serializer().equals(serializerConfig.getSerializer())) {
                serializer = (AbstractRedisSerializer) bean;
                logger.info("Redis序列化默认方式:" + epfuseRedisSerializer.serializer());
            }
        }
        if (AbstractRedisSerializer.isEmpty(serializer)) {
            serializer = new JdkSerializer();
            logger.info("Redis序列化默认方式:jdk");
        }
    }
}
